--
-- @Author:      name
-- @DateTime:    2018-08-9 23:05:48
-- @Description: 消息处理

local skynet = require "skynet"
local log = require "Logger"
local Network = require "Network"
local config = require "configquery"
local Timer = require "timer"
local FSM = require "fsm"
local HallHandler = require "HallHandler"
local GameHandler = require "GameHandler"
local Ai = require "Ai"

local MessageHandler = class("MessageHandler")

---------------------------------------------------------
-- Private
---------------------------------------------------------
function MessageHandler:ctor(message_dispatch)
	
	self.message_dispatch = message_dispatch	
	self.user_sockets = {} --用户连接的基本信息
	self.node_message = node_message
	local ip = "127.0.0.1"
	local port = 12101
	self.network = Network.new(ip,port)
	self.cmd = nil
	self.user_id = nil
	self.is_banker = false
	self.character = {} --行为配置
	self.can_look_card = false --能看牌
	self.ai = Ai.new(config.robot_zjh_config)

	self.timer = Timer:new()
	self.max_wait_time = math.random(30,60)
	self.hallHandler = nil
	self.gameHandler = nil
	self.first_enter = true --第一次进入桌子，不随机换桌
	-- 注册消息
	self:register()

	-- 定时器，退出游戏
	self:checkStatus(true)
end

--注册本服务里的消息
function MessageHandler:register()

	self.message_dispatch:register('init',handler(self,self.init))


	-- 场景消息
	self:registerGameMessage( "MSG_G2C_SceneGameIdle", handler(self,self.sceneGameIdlezNt))
	-- self:registerGameMessage( "MSG_G2C_SceneRobBanker", handler(self,self.sceneRobBankerNt))
	self:registerGameMessage( "MSG_G2C_SceneBetJetton", handler(self,self.sceneBetNt))
	-- self:registerGameMessage( "MSG_G2C_SceneBrightCard", handler(self,self.sceneBrightCardNt))

	-- 发牌
	self:registerGameMessage( "MSG_G2C_DealCard", handler(self,self.dealCardNt))
	-- self:registerGameMessage( "MSG_G2C_StartRobBanker", handler(self,self.robBankerNt))
	-- 确定庄
	self:registerGameMessage( "MSG_G2C_ChooseBankerNotify", handler(self,self.chooseBankerNt))
    -- 下注开始
	self:registerGameMessage( "MSG_G2C_StartBetJetton", handler(self,self.startBetNt))
	-- 玩家下注
	self:registerGameMessage( "MSG_G2C_BetJettonNotify", handler(self,self.userBetNt))
	-- 下注结果
	self:registerGameMessage( "MSG_G2C_BetJettonResult", handler(self,self.userBetRes))

	-- 比牌通知
	self:registerGameMessage( "MSG_G2C_CompareCardNotify", handler(self,self.compareCardNt))
	-- 比牌结果
	self:registerGameMessage( "MSG_G2C_CompareCardResult", handler(self,self.compareCardRes))

    -- 看牌通知	
	self:registerGameMessage( "MSG_G2C_ShowCardNotify", handler(self,self.showCardNt))
	-- 看牌结果
	self:registerGameMessage( "MSG_G2C_ShowCardResult", handler(self,self.showCardRes))

    -- 弃牌通知	
	self:registerGameMessage( "MSG_G2C_FoldCardNotify", handler(self,self.foldCardNt))
	-- 弃牌结果
	self:registerGameMessage( "MSG_G2C_FoldCardResult", handler(self,self.foldCardRes))
	   
    -- //亮牌
	self:registerGameMessage( "MSG_G2C_BrightCardNotify", handler(self,self.brightCardNt))
	self:registerGameMessage( "MSG_G2C_BrightCardResult", handler(self,self.brightCardRes))

    -- //结算
	self:registerGameMessage( "MSG_G2C_GameSettlement", handler(self,self.settlementNt))

    -- 暗注
	self:registerGameMessage( "MSG_G2C_AnteBetJettonNotify", handler(self,self.anteBetNt))
    -- 跟注到底
	self:registerGameMessage( "MSG_G2C_CallToEndNotify", handler(self,self.callToEndNt))
    -- 跟注到底结果
	self:registerGameMessage( "MSG_G2C_CallToEndResult", handler(self,self.callToEndRes))	
    -- 广播全场比牌
	self:registerGameMessage( "MSG_G2C_AllCompareCardNotify", handler(self,self.allCompareCardNt))


end

-- 初始化玩家信息
function MessageHandler:init(pbc_env, user_info)
	print("________user___init__________")



	self.cmd = config.message_cmd

	local robot_character_set = config.robot_zjh_set.character
	local character_type = math.random(1,3) --性格类型
	self.character = robot_character_set[character_type]
	self.user_info = user_info
	
	print("___self.character__",self.character)
	self.network:init(pbc_env)
	self.hallHandler = HallHandler.new(self.message_dispatch, self.network, user_info)
	self.gameHandler = GameHandler.new(self.message_dispatch, self.network, user_info, self)
end

function MessageHandler:registerByName(package_name, message_name, callback)
	if not callback then 
		callback = handler(self,self[message_name])
	end
	self.network:register(package_name..message_name, callback)
end

function MessageHandler:registerGameMessage(message_name, callback)
	local package_name = "proto.msg.game_zjh."
	self:registerByName(package_name,  message_name, callback)
end

function MessageHandler:exit()
	print("________退出游戏_________")
	self.network:close()
	skynet.exit()
end

function MessageHandler:print(...)
	-- if self.user_id == 39 then 
		print(...)
	-- end
end
function MessageHandler:checkError(data)
	if data.error_code and data.error_code > 0 then 
		self:exit()
	end
end

function MessageHandler:checkStatus(check)
	-- 长时间处于等待状态的机器人，自动退出
	if check then 
		self.timer_check_status = self.timer:register(self.max_wait_time, nil, handler(self, self.exit))
	elseif self.timer_check_status then 
		self.timer:unregister(self.timer_check_status)
	end
end

-- 暂停主协程
function MessageHandler:sleep(times)
	local time = math.random(times[1],times[2]) * 100
	print("________sleep__time___",time)
	skynet.sleep(time)
end

-- 取下注值
function MessageHandler:getBetNum()

	return 1
end

--换桌
function MessageHandler:changeTable()
	local nums = self.character.change_desk
	local num = math.random(1,100)
	if num >= nums[1] and num <= nums[2] then 
		self:exit()
		return true
	end	
	return false
end


---------------------------------------------------------------
--req
---------------------------------------------------------------
--用户准备
function MessageHandler:userReadyReq(data)
	if not self.first_enter then 
		local res = self:changeTable() --可能换桌	
		if res then return end	
	end	
	local times = self.character.ready_speed
	self:sleep(times)
	-- print("________ready_over_",os.time() - time)
	local body = {
		extend_data = {1},
	}
	self.network:send(self.cmd.DMSG_MDM_GAME,self.cmd.DMSG_C2G_UserReady,body)
end
--下注请求
function MessageHandler:betJettonReq(bet_num, bet_type)
	-- if self.is_banker then --庄不用下注
	-- 	return 
	-- end
    -- NO_OPERATE = 0, --无操作
    -- --下注相关
    -- CALL = 1,   --跟注
    -- RAISE = 2,  --加注
    -- CALL_TO_END = 3,   --跟到底
    -- --
    -- SHOWCARD = 4,  --看牌
    -- FOLD = 5,  --弃牌
    -- COMPARECARD = 6,  --比牌
    -- ANTE =7,--下前注
    -- --跟注时的，特殊状态，可以与CALL状态并存,做显示用
    -- ALLBET = 128, --封顶后，进入可全下轮，下注所有剩余筹码
    -- ALLIN = 256, --除了前面的全下状态ALLBET，其他下注所有剩余筹码均为ALLIN状态	
    local tb_oper = {1,2,3}
	local body = {
		seat_id = self.user_info.seat_id,
		bet_jetton = bet_num or 1,
		bet_type = bet_type or tb_oper[math.random(1,#tb_oper)]
	}
	print("___________self.cmd.DMSG_C2G_BetJetton______",body,self.character.bet_speed)
	self:sleep(self.character.bet_speed)	
	self.network:send(self.cmd.DMSG_MDM_GAME_ZJH,self.cmd.DMSG_C2G_BetJetton,body)    	
end
-- 比牌请求
function MessageHandler:compareCardReq(data)
	local body = {
		seat_id = self.user_info.seat_id,	
		compare_seat_id = nil, --请求与比牌的位置	
	}
	self.network:send(self.cmd.DMSG_MDM_GAME_ZJH,self.cmd.DMSG_C2G_CompareCard,body) 	
end
-- 看牌请求
function MessageHandler:showCardReq(data)
	-- local look = self.character.look_card
	-- local num = math.random(0, 100)
	-- if num<look[1] or num>look[2] then 
	-- 	return 
	-- end
	local body = {
		seat_id = self.user_info.seat_id,		
	}
	self:sleep(self.character.show_card_speed)	
	self.network:send(self.cmd.DMSG_MDM_GAME_ZJH,self.cmd.DMSG_C2G_ShowCard,body) 	
end
-- 弃牌请求
function MessageHandler:foldCardReq(data)
	local body = {
		seat_id = self.user_info.seat_id,		
	}	
	self:sleep(self.character.show_card_speed)	
	self.network:send(self.cmd.DMSG_MDM_GAME_ZJH,self.cmd.DMSG_C2G_FoldCard,body) 	
end

--亮牌请求
function MessageHandler:brightCardReq(data)
	local body = {
		seat_id = self.user_info.seat_id,		
	}
	self:sleep(self.character.show_card_speed)	
	self.network:send(self.cmd.DMSG_MDM_GAME_ZJH,self.cmd.DMSG_C2G_BrightCard,body) 	
end

--跟注到底请求
function MessageHandler:callToEndReq(data)
	local body = {
		seat_id = self.user_info.seat_id,
		multiple = 1,
	}
	self:sleep(self.character.rob_banker_speed)
	self.network:send(self.cmd.DMSG_MDM_GAME_ZJH,self.cmd.DMSG_C2G_CallToEnd,body)    
end

---------------------------------------------------------------
--res
---------------------------------------------------------------

--下注结果
function MessageHandler:userBetRes(data)
	self:print("__下注结果_____",data)
	if data.error_code==7 then 
		--首轮庄家位不能加注
		self:betJettonReq(1,1)
	end
end

--玩家比牌结果
function MessageHandler:compareCardRes(data)
	self:print("__比牌结果_____",data)
end

--看牌结果
function MessageHandler:showCardRes(data)
	self:print("__看牌结果_____",data)
	self.can_look_card = false
end

--弃牌结果
function MessageHandler:foldCardRes(data)
	self:print("__弃牌结果_____",data)
	if data.error_code==4 then 
		--首轮庄家位不能加注
		self:betJettonReq(1,1)
	end	
end

--亮牌结果
function MessageHandler:brightCardRes(data)
	self:print("__亮牌结果_____",data)
end

--跟注到底结果
function MessageHandler:callToEndRes(data)
	self:print("__跟注到底结果_____",data)
end


---------------------------------------------------------------
--nt
---------------------------------------------------------------
function MessageHandler:sceneGameIdlezNt(data)
	self:print("__空场景___MG_G2C_SceneGameIdle_____",data)

	if not self.first_enter then 
		if self:changeTable() then --可能换桌	
			return 
		end
	end
	self.first_enter = false
	self:userReadyReq() --准备
end
function MessageHandler:sceneRobBankerNt(data)
	self:print("__抢庄场景___MSG_G2C_SceneRobBanker_____",data)

end
function MessageHandler:sceneBetNt(data)
	self:print("__下注场景___MSG_G2C_SceneBetJetton_____",data)

end
function MessageHandler:sceneBrightCardNt(data)
	self:print("__亮牌场景___MSG_G2C_SceneBrightCard_____",data)

end

--发牌
function MessageHandler:dealCardNt(data)
	self:print("__收到发牌___MG_G2C_SceneGameIdle_____",data)		

	self.ai:setCard(data, self.user_info.seat_id)
end

-- -- 开始抢庄
-- function MessageHandler:robBankerNt(data)
-- 	self:print("__开始抢庄___MSG_G2C_StartRobBanker_____",data)
-- 	self:robBankerReq()
-- end

function MessageHandler:chooseBankerNt(data)
	self:print("__庄家确定___MSG_G2C_ChooseBanker_____",data)
    if self.user_info.seat_id == data.banker_seat_id then 
    	self.is_banker = true
    end
    self:checkStatus(false)
    self.can_look_card = false
end

--开始下注
function MessageHandler:startBetNt(data)
	self:print("__开始下注通知_____",data)
	if self.can_look_card then
		if self.ai:canLookCard() then  
			--能看牌
			self:showCardReq()
		end
	end	
	if self.user_info.seat_id ~= data.bet_info.bet_seat_id then 
		return 
	end
	if data.bet_info.can_showcard then 
		self.can_look_card = true
	end
	local round = data.bet_info.current_round
	local can_compare = data.bet_info.can_comparecard
	local oper_id = self.ai:run(round, can_compare)
	local can_fold = data.bet_info.can_fold

	print("_______oper_id___",oper_id)
	--不能弃牌
	if oper_id==4 and not can_fold then 
		oper_id = 1
	end	
	-- 1跟注，2加注，3比牌， 4弃牌
	if oper_id == 1 then 
		local bet_num = data.bet_info.call_jetton
		self:betJettonReq(bet_num ,1)
	elseif oper_id == 2 then 
		local bet_num = data.bet_info.raise_jetton[1]
		print("______加注___", bet_num)
		self:betJettonReq(bet_num ,2)		
	elseif oper_id == 3 then 
		self:compareCardReq()
	elseif oper_id == 4 then 
		self:foldCardReq()		
	end

	-- --跟注，加注，比牌，弃牌，全下
	-- local probability = self.character.oper
	-- local num = math.random(1,100)
	-- print("____num_________",num)
	-- if num < probability[4] and data.bet_info.can_fold then 
	-- 	self:foldCardReq()
	-- elseif num < probability[3] and data.bet_info.can_comparecard then 
	-- 	self:compareCardReq()
	-- elseif num < probability[2] and data.bet_info.can_raise then 	
	-- 	local bet_num = data.bet_info.raise_jetton[1]
	-- 	print("______加注___", bet_num)
	-- 	self:betJettonReq(bet_num ,2)
	-- elseif num < probability[1] then 
	-- 	local bet_num = data.bet_info.call_jetton
	-- 	self:betJettonReq(bet_num ,1)
	-- else
	-- 	local bet_num = data.bet_info.call_jetton
	-- 	self:betJettonReq(bet_num ,1)			
	-- end


end

--玩家下注通知
function MessageHandler:userBetNt(data)
	self:print("__玩家下注通知_____",data)
end

--玩家比牌通知
function MessageHandler:compareCardNt(data)
	self:print("__玩家比牌通知_____",data)
end

--看牌通知
function MessageHandler:showCardNt(data)
	self:print("__看牌通知_____",data)
end

--弃牌通知
function MessageHandler:foldCardNt(data)
	self:print("__弃牌通知_____",data)
end

--亮牌通知
function MessageHandler:brightCardNt(data)
	self:print("__亮牌通知_____",data)
end

--结算
function MessageHandler:settlementNt(data)
	self:print("__结算结果_____",data)
	local seat_list = data.settle_list
	for k,v in pairs(seat_list) do 
		if v.seat_id==self.user_info.seat_id and v.win_lose==true then 
			--赢了亮牌
			self:brightCardReq()
		end
	end
	self:checkStatus(true)

end

--跟注到底通知
function MessageHandler:callToEndNt(data)
	self:print("__跟注到底通知_____",data)


end

--暗注通知
function MessageHandler:anteBetNt(data)
	self:print("__暗注通知_____",data)

end

--全局比牌
function MessageHandler:allCompareCardNt(data)
	self:print("__全局比牌_____",data)

end
  



return MessageHandler